package com.concurrency.example.completionService;

import lombok.extern.slf4j.Slf4j;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * CompletionService作用：可以保存多个提交的任务的Future，方便获取批量任务的执行结果
 * 原理：ExecutorCompletionService 维护了一个队列来存放Future，每次submit都会创建一个QueueingFuture包装Callable，
 *       QueueingFuture重写了FutureTask的done方法，让把执行完毕的任务Future添加到队列中。
 */
@Slf4j
public class CompletionServiceTest {
    private static Integer TASK_COUNT = 100;
    private static Integer THREAD_COUNT = 10;
    public static void main(String[] args) {

        List<Callable<String>> taskList = new ArrayList<>();
        for (int i = 0; i < TASK_COUNT; i++) {
            taskList.add(new Task());
        }
        long startTime = System.currentTimeMillis();
        //提交任务
        ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT);
        CompletionService<String> completionService = new ExecutorCompletionService(executorService);
//        for (int i = 0; i < TASK_COUNT; i++) {
//            completionService.submit(taskList.get(i));
//        }
//
//        //获取执行结果
//        try {
//            for (int i = 0; i < TASK_COUNT; i++) {
//                //take()获取并删除队列头元素
//                Future<String> future = completionService.take();
//
//                System.out.println(future.get());
//            }
//        } catch (InterruptedException e1) {
//            Thread.currentThread().interrupt();
//        } catch (ExecutionException e2) {
//            e2.printStackTrace();
//        }

        /*
            invokeAll()方法：当所有任务都执行完毕时会返回
         */
//        try {
//            List<Future<String>> futureList = executorService.invokeAll(taskList);
//            for (Future<String> future : futureList) {
//                System.out.println(future.get());
//            }
//        } catch (Exception e) {
//
//        }


        log.info("执行时间：{}", (System.currentTimeMillis() - startTime));
    }
}
